#include "sm4.h"
#include "common_func.h"
#include "core_time.h"
#include <string.h>

uint32_t sm4_clear(void)
{
	RegWrite(SM4_ENABLE, 0x00);
	RegWrite(SM4_KEY_EXP_IN, 0x00);
	RegWrite(SM4_VALID, 0x00);
	RegWrite(SM4_KEY_VALID, 0x00);
	RegWrite(SM4_ENC_DEC_ENABLE, 0x00);
	
	return 0;
}

uint32_t sm4_init(uint32_t mode, uint8_t* key)
{
	//copy key
	uint32_t user_key[4];
	memcpy(user_key, key, 16);
	
	//enable
	RegWrite(SM4_ENABLE, 0x01);
	
	//enc or dec
	if(mode == 0)//enc
	{
		RegWrite(SM4_ENC_DEC_SEL, 0x00);
	}
	else//dec
	{
		RegWrite(SM4_ENC_DEC_SEL, 0x01);
	}
	
	//key
	RegWrite(SM4_KEY_EXP_IN, 0x01);
	RegWrite(SM4_KEY_0, user_key[0]);
	RegWrite(SM4_KEY_1, user_key[1]);
	RegWrite(SM4_KEY_2, user_key[2]);
	RegWrite(SM4_KEY_3, user_key[3]);
	RegWrite(SM4_KEY_VALID, 0x01);
	
	//wait key
	while(RegRead(SM4_KEY_EXP_OUT) == 0x00)
	{
		delay_ms(SM4_WAIT_TIME);
	}
	
	return 0;
}

//调用前需先获取密钥使用权限
uint32_t sm4_init_inkey(uint32_t mode)
{	
	//enable
	RegWrite(SM4_ENABLE, 0x01);
	
	//enc or dec
	if(mode == 0)//enc
	{
		RegWrite(SM4_ENC_DEC_SEL, 0x00);
	}
	else//dec
	{
		RegWrite(SM4_ENC_DEC_SEL, 0x01);
	}
	
	//key
	RegWrite(SM4_KEY_EXP_IN, 0x01);
	RegWrite(SM4_KEY_VALID, 0x01);
	
	//wait key
	while(RegRead(SM4_KEY_EXP_OUT) == 0x00)
	{
		delay_ms(SM4_WAIT_TIME);
	}
	
	return 0;
}

uint32_t sm4_enc_dec_int(uint8_t* data)
{
	// not init
	if(RegRead(SM4_KEY_EXP_OUT) == 0x00)
	{
		return 0x01;// not init
	}
	else
	{
		//copy data
		uint32_t user_data[4];
		memcpy(user_data, data, 16);	
		
		RegWrite(0xbf20f004, 0x20);//edge	边沿
		RegWrite(0xbf20f008, 0x20);//pol  高电平
		RegWrite(0xbf20f00c, 0x20);//clr
		RegWrite(0xbf20f000, 0x20);//en
		RegWrite(SM4_ENABLE_INT, 0x1);//en
		
		//enc_dec enable
		RegWrite(SM4_ENC_DEC_ENABLE, 0x01);
		
		//data
		RegWrite(SM4_DATA_0, user_data[0]);
		RegWrite(SM4_DATA_1, user_data[1]);
		RegWrite(SM4_DATA_2, user_data[2]);
		RegWrite(SM4_DATA_3, user_data[3]);
		RegWrite(SM4_VALID, 0x01);
	}
	
	return 0;
}

uint32_t sm4_enc_dec_callback(uint8_t * result)
{
	uint32_t result_data[4];

	//copy result
	result_data[0] = RegRead(SM4_RESULT_0);
	result_data[1] = RegRead(SM4_RESULT_1);
	result_data[2] = RegRead(SM4_RESULT_2);
	result_data[3] = RegRead(SM4_RESULT_3);
	memcpy(result, result_data, 16);
	
	return 0;
}

uint32_t sm4_enc_dec(uint8_t* data, uint8_t * result)
{
	// not init
	if(RegRead(SM4_KEY_EXP_OUT) == 0x00)
	{
		return 0x01;// not init
	}
	else
	{
		//copy data
		uint32_t user_data[4];
		uint32_t result_data[4];
		memcpy(user_data, data, 16);	
		
		//enc_dec enable
		RegWrite(SM4_ENC_DEC_ENABLE, 0x01);
		
		//data
		RegWrite(SM4_DATA_0, user_data[0]);
		RegWrite(SM4_DATA_1, user_data[1]);
		RegWrite(SM4_DATA_2, user_data[2]);
		RegWrite(SM4_DATA_3, user_data[3]);
		RegWrite(SM4_VALID, 0x01);
		
		//wait key
		while(RegRead(SM4_READY) == 0x00)
		{
			delay_ms(SM4_WAIT_TIME);
		}
		
		//copy result
		result_data[0] = RegRead(SM4_RESULT_0);
		result_data[1] = RegRead(SM4_RESULT_1);
		result_data[2] = RegRead(SM4_RESULT_2);
		result_data[3] = RegRead(SM4_RESULT_3);
		memcpy(result, result_data, 16);
	}
	
	return 0;
}